package com.sunwayworld.basemodule.rm.material.io;

import com.sunwayworld.baseline.framework.override.LimsExcelHelper;
import com.sunwayworld.basemodule.rm.material.bean.LimsMaterialBean;
import com.sunwayworld.basemodule.rm.material.service.LimsMaterialService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.io.file.FilePathDTO;
import com.sunwayworld.framework.io.file.FilePathManager;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.framework.utils.BeanUtils;
import com.sunwayworld.framework.utils.CollectionUtils;
import com.sunwayworld.framework.utils.NumberUtils;
import com.sunwayworld.framework.utils.StringUtils;
import com.sunwayworld.module.item.file.bean.CoreFileBean;
import com.sunwayworld.module.item.file.bean.CoreFileImportResultDTO;
import com.sunwayworld.module.item.file.function.CoreFileImportFunction;
import com.sunwayworld.module.item.file.utils.CoreFileUtils;
import com.sunwayworld.module.sys.code.bean.CoreCodeBean;
import com.sunwayworld.module.sys.code.service.CoreCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xiongym 2020年4月15日
 */
@Component(value = "LimsMaterialImportFileFunction")
@GikamBean
public class LimsMaterialImportFileFunction implements CoreFileImportFunction {


    @Autowired
    @Lazy
    private LimsMaterialService materialService;

    @Autowired
    @Lazy
    private CoreCodeService coreCodeService;

    @Override
    @Transactional
    public CoreFileImportResultDTO apply(CoreFileBean coreFileBean) {
        CoreFileImportResultDTO importResultRepresentation = new CoreFileImportResultDTO();
        FilePathDTO fr = CoreFileUtils.toFilePath(coreFileBean);
        List<LimsMaterialBean> materialBeans = LimsExcelHelper.readDataFromExcel(FilePathManager.getLocalPath(fr).toString(), 1, 2, LimsMaterialBean.class);
        if (CollectionUtils.isEmpty(materialBeans)) {
            throw new InvalidDataException("导入表格非法！");
        }

        List<String> columns = Arrays.asList("matCode", "matName", "matTypeCode", "brand", "minimum");
        List<String> colNames = Arrays.asList("【材料编号】", "【材料名称】", "【材料类型】", "【品牌】", "低限");
        materialBeans.forEach(a -> {
            StringBuilder msg = new StringBuilder();
            for (int i = 0; i < columns.size(); i++) {
                Object value = BeanUtils.getPropertyValue(a, columns.get(i));
                if (value == null || (value.getClass().equals(String.class) && value.equals(""))) {
                    msg.append(colNames.get(i));
                }
            }
            if (msg.length() > 0) {
                msg.append(" 为必填项；");
            }
            if (msg.length() > 0) {
                if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                    a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat(msg.toString()));
                } else {
                    a.setExt$Item("validateimpmsg", msg.toString());
                }
            }
        });
        Map<String, List<LimsMaterialBean>> groupByMatCode = materialBeans.stream().filter(m -> !StringUtils.isBlank(m.getMatCode())).collect(Collectors.groupingBy(LimsMaterialBean::getMatCode));
        groupByMatCode.forEach((c, temp) -> {
            if (temp.size() > 1) {
                temp.forEach(a -> {
                    if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                        a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("表格中字段【材料编码】存在重复；"));
                    } else {
                        a.setExt$Item("validateimpmsg", "表格中字段【材料编码】存在重复；");
                    }
                });
            }
        });
        List<LimsMaterialBean> exists = materialService.selectListByFilter(SearchFilter.instance().match("MATCODE", new ArrayList<>(groupByMatCode.keySet())).filter(MatchPattern.OR));
        exists.forEach(e -> {
            List<LimsMaterialBean> temp = groupByMatCode.get(e.getMatCode());
            if (temp != null && !temp.isEmpty()) {
                temp.forEach(a -> {
                    if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                        a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("【材料编码】重复导入；"));
                    } else {
                        a.setExt$Item("validateimpmsg", "【材料编码】重复导入；");
                    }
                });
            }
        });

        // 返还校验结果
        if (materialBeans.stream().anyMatch(i -> !StringUtils.isEmpty(i.getExt$Item("validateimpmsg")))) {
            FilePathDTO filePathDTO = LimsExcelHelper.writeImportFailureListAsExcel(FilePathManager.getLocalPath(fr).toString(), materialBeans, 1, 2, "导入错误信息.xlsx", false);
            importResultRepresentation.setUrl(FilePathManager.getUrl(filePathDTO));
            importResultRepresentation.setMessage("导入失败");
            return importResultRepresentation;
        }

        List<String> idList = ApplicationContextHelper.getNextSequenceList(materialService.getDao().getTable(), materialBeans.size());
        final int[] i = {0};
        List<CoreCodeBean> codeBeans = coreCodeService.selectListByFilter(SearchFilter.instance().match("codeCategoryId", "materialType").filter(MatchPattern.EQ));
        List<CoreCodeBean> units = coreCodeService.selectListByFilter(SearchFilter.instance().match("codeCategoryId", "unitCategory").filter(MatchPattern.EQ));
        materialBeans.forEach(s -> {
            s.setId(NumberUtils.parseLong(idList.get(i[0])));
            s.setMatTypeName(s.getMatTypeCode());
            Optional<CoreCodeBean> optional = codeBeans.stream().filter(c -> c.getCodeName().equals(s.getMatTypeCode())).findAny();
            if (optional.isPresent()) {
                s.setMatTypeCode(optional.get().getCode());
            } else {
                s.setMatTypeCode("");
                s.setMatTypeName("");
            }
            if (s.getMatNum() == null) {
                s.setMatNum(0.0);
            }
            if (StringUtils.isBlank(s.getMinimum())) {
                s.setMinimum("0");
            }
            if (!StringUtils.isBlank(s.getDefaultUnitCode())) {
                units.stream().filter(u -> u.getCodeName().equals(s.getDefaultUnitCode())).findAny().ifPresent(u -> {
                    s.setDefaultUnitCode(u.getCode());
                });
            }
            if (!StringUtils.isBlank(s.getPurchaseUnitCode())) {
                units.stream().filter(u -> u.getCodeName().equals(s.getPurchaseUnitCode())).findAny().ifPresent(u -> {
                    s.setPurchaseUnitCode(u.getCode());
                });
            }
            if (!StringUtils.isBlank(s.getStorageUnitCode())) {
                units.stream().filter(u -> u.getCodeName().equals(s.getStorageUnitCode())).findAny().ifPresent(u -> {
                    s.setStorageUnitCode(u.getCode());
                });
            }
            i[0]++;
        });
        materialService.getDao().insert(materialBeans);
        importResultRepresentation.setMessage("导入成功");
        return importResultRepresentation;
    }

    @Override
    public boolean test(CoreFileBean coreFile, String service) {
        return true;
    }
}
